﻿namespace Journey.Application.Users
{
    using Journey.Adapter;
    using Journey.Domain.Users;
    using Journey.DTO.Users;
    using Journey.Logging;
    using Journey.Security;

    using System;

    /// <summary>
    /// 用户应用服务。
    /// </summary>
    public class UserAppService : IUserAppService
    {
        #region 字段

        /// <summary>
        /// 用户数据访问器。
        /// </summary>
        private readonly IUserRepository _userRepository;

        #endregion 字段

        #region 构造器

        /// <summary>
        /// 初始化用户应用服务。
        /// </summary>
        /// <param name="userRepository">用户数据访问器。</param>
        public UserAppService(IUserRepository userRepository)
        {
            _userRepository = userRepository;

            Logger = LoggerFactory.Current.Create();
        }

        #endregion 构造器

        #region 日志记录器

        /// <summary>
        /// 日志记录器。
        /// </summary>
        protected ILogger Logger { get; set; }

        #endregion 日志记录器

        #region 获得用户详细信息

        /// <summary>
        /// 获得用户详细信息。
        /// </summary>
        /// <param name="accountNumber">用户怅号。</param>
        /// <returns>用户详细信息。</returns>
        public UserDTO GetUser(string accountNumber)
        {
            var user = _userRepository.GetUser(accountNumber);

            if (user != null)
            {
                return user.ProjectedAs<UserDTO>();
            }

            Logger.LogWarning(Messages.Warning_InvalidArgumentForGetUser);
            return null;
        }

        #endregion 获得用户详细信息

        #region 注册新用户

        /// <summary>
        /// 注册新用户。
        /// </summary>
        /// <param name="userDTO">用户注册数据。</param>
        /// <returns>注册新用户操作状态。</returns>
        public RegisterNewUserStatus RegisterNewUser(UserDTO userDTO)
        {
            if (userDTO == null)
            {
                throw new ArgumentNullException("userDTO", "userDTO 对象不可以是 null。");
            }

            var user = UserFactory.Create(userDTO.AccountNumber, userDTO.Password, userDTO.Name, userDTO.Email);

            var result = this.SaveUser(user);

            return result ? RegisterNewUserStatus.Success : RegisterNewUserStatus.Error;
        }

        /// <summary>
        /// 保存用户
        /// </summary>
        /// <param name="user">新用户信息。</param>
        private bool SaveUser(User user)
        {
            this._userRepository.Create(user);
            this._userRepository.Flush();
            return true;
        }

        #endregion 注册新用户

        #region 释放资源

        /// <summary>
        /// 释放资源。
        /// </summary>
        public void Dispose()
        {
            this._userRepository.Dispose();
        }

        #endregion 释放资源
    }
}